package cn.net.asiacom.extrator;

import cn.net.asiacom.entity.Original;
import cn.net.asiacom.entity.Ticket;
import cn.net.asiacom.utils.ReceiptFileUtil;
import cn.net.asiacom.utils.StrUtil;

import java.io.File;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.net.asiacom.config.RegexEnum.*;

/**
 * 获取火车车票信息
 */
public class TrainTicketExtractor {

    private TrainTicketExtractor() {}

    /**
     * 从本地文件或URL中提取发票信息。
     */
    public synchronized static Ticket extractTicket(String filePath) {
        return extractTicket(new File(filePath));
    }

    /**
     * 从本地文件或URL中提取发票信息。
     */
    public synchronized static Ticket extractTicket(File pdfFile) {
        Original original = ReceiptFileUtil.processFile(pdfFile);
        Ticket ticket = getTicketETicketNumber(original.getFullText(), new Ticket());
        if (StrUtil.isBlank(ticket.getETicketNumber())) {
            ReceiptFileUtil.close(original.getDoc());
            throw new RuntimeException("无效火车票");
        }
        getTicketNumber(original.getFullText(), ticket);
        if (StrUtil.isBlank(ticket.getNumber())) {
            ReceiptFileUtil.close(original.getDoc());
            throw new RuntimeException("非火车票");
        }
        getTicketDate(original.getFullText(), ticket);
        getTicketAmount(original.getFullText(), ticket);
        getTicketItinerary(original.getFullText(), ticket);
        getTicketDepartureSeatInformation(original.getFullText(), ticket);
        getTicketPassengerInfo(original.getFullText(), ticket);
        getTicketBuyer(original.getFullText(), ticket);
        ReceiptFileUtil.close(original.getDoc());
        return ticket;
    }

    /**
     * 提取发票号码
     * @param allText
     * @param ticket
     * @return
     */
    private synchronized static Ticket getTicketNumber(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_NUMBER.getRegex());
        Matcher m00 = pattern.matcher(allText);
        if (m00.find()) {
            ticket.setNumber(m00.group("number"));
        }
        return ticket;
    }
    /**
     * 提取发票日期
     * @param allText 发票文本
     * @return 发票信息
     */
    private synchronized static Ticket getTicketDate(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_DATE.getRegex());
        Matcher date = pattern.matcher(allText);
        if (date.find()) {
            String rawDate = date.group("date");
            SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
            SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date parsedDate = null;
            try {
                parsedDate = inputDateFormat.parse(rawDate);
            } catch (ParseException e) {
                throw new RuntimeException("无法解析日期：" + rawDate);
            }
            String formattedDate = outputDateFormat.format(parsedDate);
            ticket.setDate(formattedDate);
        }
        return ticket;
    }
    /**
     * 提取票价
     * @param allText 发票文本
     * @return 发票信息
     */
    private synchronized static Ticket getTicketAmount(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_AMOUNT.getRegex());
        Matcher amount = pattern.matcher(allText);
        if (amount.find()) {
            String group = amount.group(1);
            ticket.setAmount(new BigDecimal(group));
        }
        return ticket;
    }
    /**
     * 提取始发站终点站及车次
     * @param allText
     * @param ticket
     * @return
     */
    private synchronized static Ticket getTicketItinerary(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_STATION.getRegex());
        Matcher itinerary = pattern.matcher(allText);
        if (itinerary.find()) {
            ticket.setDepartureStation(itinerary.group(1));
            ticket.setTrainNumber(itinerary.group(2));
            ticket.setDestinationStation(itinerary.group(3));
        }
        return ticket;
    }
    /**
     * 提取发车座位信息
     * @param allText
     * @param ticket
     * @return
     */
    private synchronized static Ticket getTicketDepartureSeatInformation(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_TRAIN.getRegex());
        Matcher itinerary = pattern.matcher(allText);
        if (itinerary.find()) {
            ticket.setDepartureDate(itinerary.group(1));
            ticket.setDepartureTime(itinerary.group(2));
            ticket.setSeatNumber(itinerary.group(3) + itinerary.group(4));
            ticket.setSeatType(itinerary.group(5));
        }
        return ticket;
    }
    /**
     * 提取乘客信息
     * @param allText
     * @param ticket
     * @return
     */
    private synchronized static Ticket getTicketPassengerInfo(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_PASSENGER.getRegex());
        Matcher passenger = pattern.matcher(allText);
        if (passenger.find()) {
            ticket.setPassengerNumber(passenger.group(1));
            ticket.setPassengerName(passenger.group(2));
        }
        return ticket;
    }
    /**
     * 提取乘客信息 电子客票号
     * @param allText
     * @param ticket
     * @return
     */
    private synchronized static Ticket getTicketETicketNumber(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_E_TICKET_NUMBER.getRegex());
        Matcher ticketNumber = pattern.matcher(allText);
        if (ticketNumber.find()) {
            ticket.setETicketNumber(ticketNumber.group(1));
        }
        return ticket;
    }
    /**
     * 提取购买方名称及统一社会信用代码
     * @param allText
     * @param ticket
     * @return
     */
    private synchronized static Ticket getTicketBuyer(String allText, Ticket ticket) {
        Pattern pattern = Pattern.compile(TICKET_INVOICE_BUYER.getRegex());
        Matcher buyerMatcher = pattern.matcher(allText);
        if (buyerMatcher.find()) {
            String buyerName = buyerMatcher.group(1);
            String socialCreditCode = buyerMatcher.group(2);
            ticket.setBuyerName(buyerName);
            ticket.setSocialCreditCode(socialCreditCode);
        }
        return ticket;
    }
}
